using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Beaker.Collections;
using Beaker.FileSystem;

namespace OpenCube.IO.Overload
{
	internal abstract class OverloadingEntry<TEntryType>
		: IFileSystemEntry
		where TEntryType : IFileSystemEntry
	{
		private readonly IReadOnlyList<TEntryType> _entries;
		private readonly TEntryType _lastEntry;
		private readonly OverloadingFolder _parent;

		internal OverloadingEntry(OverloadingFolder parent, IEnumerable<TEntryType> entries)
		{
			Contract.Requires<ArgumentNullException>(entries != null);
			Contract.Requires(entries.Any(), "At least one entry is required");

			_entries = entries.ToReadOnlyList();
			_lastEntry = _entries.Last();
			_parent = parent;
		}

		/// <summary>
		/// Gets the sequence of all entries this overloading entry encompasses
		/// </summary>
		protected IEnumerable<TEntryType> Entries
		{
			get
			{
				Contract.Ensures(Contract.Result<IEnumerable<TEntryType>>() != null);
				Contract.Ensures(Contract.Result<IEnumerable<TEntryType>>().Any());

				foreach (TEntryType entry in _entries)
					yield return entry;
			}
		}

		/// <summary>
		/// Gets the active entry (i.e. the most overloaded one)
		/// </summary>
		protected TEntryType ActiveEntry
		{
			get { return _lastEntry; }
		}

		public IFileSystemEntryMetadata GetMetadata()
		{
			return _entries.Last().GetMetadata();
		}

		public Task<IFileSystemEntryMetadata> GetMetadataAsync(CancellationToken cancellationToken)
		{
			throw new NotImplementedException();
		}

		/// <summary>
		/// Gets the name of the entry
		/// </summary>
		public string Name
		{
			get { return ActiveEntry.Name; }
		}

		/// <summary>
		/// Get the folder this entry is in
		/// </summary>
		public IFolder ParentFolder
		{
			get { return _parent; }
		}
	}
}